home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / genglob.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  17.3 KB  |  586 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * This file contains routines for 68k code generation.  These routines handle
  35.  * global variables and functions.
  36.  * 
  37.  * 
  38.  * 
  39.  */
  40.  
  41.  
  42. #include "conditcomp.h"
  43. #include <stdio.h>
  44. #include <ctype.h>
  45. #include <string.h>
  46. #include "structs.h"
  47.  
  48. #include "CHarvestDoc.h"
  49. #include "CHarvestOptions.h"
  50.  
  51. extern CHarvestDoc *gProject;
  52.  
  53. SYMVia_t CurrentFunctionPascal;
  54. long CurrentPascalArgs;
  55.  
  56. #pragma segment GenGlob
  57.  
  58.  
  59. void
  60. GenInitGlobal(SYMVia_t symbol, InstListVia_t Codes)
  61. {
  62.     InitDataAccIndex = 0;
  63.     ImageInit(GetSymTP(symbol), Via(symbol)->Definition.Initializer, Codes);
  64. }
  65.  
  66. void
  67. GenPLit(char *bytes, InstListVia_t Codes)
  68. /*
  69.  * Generates the DC instructions to generate a pascal string literal.
  70.  */
  71. {
  72.     int                             ndx;
  73.     int                             len;
  74.     ndx = 0;
  75.     len = strlen(bytes);
  76.     GenInst(M68op_DC, M68sz_byte, BuildAbsolute(len), NULL, Codes);
  77.     while (ndx < len) {
  78.     GenInst(M68op_DC, M68sz_byte,
  79.         BuildAbsolute((bytes)[ndx]), NULL, Codes);
  80.     ndx++;
  81.     }
  82.     /* MPW says that pascal string lits should be null terminated as well */
  83.     GenInst(M68op_DC, M68sz_byte, BuildAbsolute(0), NULL, Codes);
  84.  
  85. }
  86.  
  87. void
  88. GenLit(char *bytes, InstListVia_t Codes)
  89. /*
  90.  * Generates the DC instructions to generate a string literal.
  91.  */
  92. {
  93.     int                             ndx;
  94.     ndx = 0;
  95.     while ((bytes)[ndx]) {
  96.     GenInst(M68op_DC, M68sz_byte,
  97.         BuildAbsolute((bytes)[ndx]), NULL, Codes);
  98.     ndx++;
  99.     }
  100.     GenInst(M68op_DC, M68sz_byte, BuildAbsolute(0), NULL, Codes);
  101.  
  102. }
  103.  
  104. void
  105. GenOneLit(SYMVia_t cursym, InstListVia_t Codes)
  106. {
  107.     if (!(GetSymFlags(cursym) & CODEOUTPUT)) {
  108.     GenInst(M68op_DSEG, M68sz_none, NULL, NULL, Codes);
  109.     SetSymFlags(cursym, GetSymFlags(cursym) | CODEOUTPUT);
  110.     GenStringLabel(GetLocLabel(Via(cursym)->M68kDef.Loc), Codes);
  111. #ifdef OLDMEM
  112.     HLock((Handle) cursym);
  113. #endif
  114.     if (GetSymFlags(cursym) & ISPASCALSTRING)
  115.         GenPLit(Via(cursym)->name, Codes);
  116.     else
  117.         GenLit(Via(cursym)->name, Codes);
  118. #ifdef OLDMEM
  119.     HUnlock((Handle) cursym);
  120. #endif
  121.     }
  122. }
  123.  
  124. void
  125. GenFloatLit(char *bytes, InstListVia_t Codes)
  126. /*
  127.  * Generates the Dc instructions for a floating point literal.
  128.  */
  129. {
  130.     int                             ndx;
  131.     ndx = 0;
  132.     while (ndx < SizeOfLongDouble) {
  133.     GenInst(M68op_DC, M68sz_byte,
  134.         BuildAbsolute((long) bytes[ndx]), NULL, Codes);
  135.     ndx++;
  136.     }
  137. }
  138.  
  139. void
  140. AddStatic(SYMVia_t symbol)
  141. {
  142.     SYMVia_t                        copy;
  143.     Via(symbol)->M68kDef.Loc = BuildLabelLoc(MakeEccLabel(NextEccLabel++));
  144.     SetLocSZ(Via(symbol)->M68kDef.Loc, M68_TypeSize(GetSymTP(symbol)));
  145. #ifdef OLDMEM
  146.     HLock((Handle) symbol);
  147. #endif
  148.     copy = TableAdd(StaticTable, Via(symbol)->name);
  149.     SetSymTP(copy, GetSymTP(symbol));
  150.     Via(copy)->M68kDef.Loc = Via(symbol)->M68kDef.Loc;
  151.     #ifdef OLDMEM
  152.     HUnlock((Handle) symbol);
  153.     #endif
  154. }
  155.  
  156. void
  157. GenFloatLits(InstListVia_t Codes)
  158. /* Loop to generate all the floating point literals. */
  159. {
  160.     FloatLitVia_t                   cur;
  161.     cur = FloatList;
  162.     while (cur) {
  163.     if (!(Via(cur)->FloatFlags & CODEOUTPUT)) {
  164.         if (gProject->itsOptions->useMC68881) {
  165.             GenInst(M68op_DSEG, M68sz_none, NULL, NULL, Codes);
  166.         }
  167.         Via(cur)->FloatFlags |= CODEOUTPUT;
  168.         GenInst(M68op_EVEN, M68sz_none, NULL, NULL, Codes);
  169.         GenStringLabel(GetLocLabel(Via(cur)->Loc), Codes);
  170.         #ifdef OLDMEM
  171.         HLock((Handle) cur);
  172.         #endif
  173.         GenFloatLit(Via(cur)->val.bytes, Codes);
  174.         #ifdef OLDMEM
  175.         HUnlock((Handle) cur);
  176.         #endif
  177.     }
  178.     cur = Via(cur)->next;
  179.     }
  180. }
  181.  
  182. int
  183. AllocateParameters(SymListVia_t table, int argoff)
  184. /*
  185.  * Assigns location records to all the parameters of a function. Func
  186.  * parameters are located at positive offsets from the frame pointer.
  187.  */
  188. {
  189.     int                             offset;
  190.     SYMVia_t                        cursym;
  191.     int                             ndx;
  192.     if (!table)
  193.     return 0;
  194.     ndx = 1;
  195.     while (ndx <= Via(table)->count) {
  196.     cursym = TableGetNum(table, ndx++);
  197.     if (cursym) {
  198.         offset = argoff;
  199.         if (GetTPSize(GetSymTP(cursym)) == 1) {
  200.         offset += 3;
  201.         }
  202.         if (GetTPSize(GetSymTP(cursym)) == 2) {
  203.         offset += 2;
  204.         }
  205.         Via(cursym)->M68kDef.Loc = BuildAutoLoc(offset,
  206.                         M68_TypeSize(GetSymTP(cursym)));
  207.         argoff += GetTPSize(GetSymTP(cursym));
  208.         if ((GetTPSize(GetSymTP(cursym))) == 1)
  209.         argoff += 3;
  210.         if ((GetTPSize(GetSymTP(cursym))) == 2)
  211.         argoff += 2;
  212.         if (argoff % 2) {
  213.         argoff++;
  214.         }
  215.     }
  216.     }
  217.     return argoff;
  218. }
  219.  
  220. int
  221. AllocatePascalParameters(SymListVia_t table, int argoff)
  222. /*
  223.  * Assigns location records to all the parameters of a pascal function. Func
  224.  * parameters are located at positive offsets from the frame pointer.
  225.  */
  226. {
  227.     int                             offset;
  228.     SYMVia_t                        cursym;
  229.     int                             ndx;
  230.     if (!table)
  231.     return 0;
  232.     ndx = Via(table)->count;
  233.     while (ndx >= 1) {
  234.     cursym = TableGetNum(table, ndx--);
  235.     if (cursym) {
  236.         offset = argoff;
  237.         if (GetTPSize(GetSymTP(cursym)) == 1) {
  238.         offset += 1;
  239.         }
  240.         Via(cursym)->M68kDef.Loc = BuildAutoLoc(offset,
  241.                         M68_TypeSize(GetSymTP(cursym)));
  242.         argoff += GetTPSize(GetSymTP(cursym));
  243.         if ((GetTPSize(GetSymTP(cursym))) == 1)
  244.         argoff += 1;
  245.         if (argoff % 2) {
  246.         argoff++;
  247.         }
  248.     }
  249.     }
  250.     return argoff;
  251. }
  252.  
  253. void
  254. Allocate2Locals(SymListVia_t table, InstListVia_t Codes)
  255. /*
  256.  * Assign location records to the local variables for a block.  All the
  257.  * locals for all the blocks within a single function are allocated on the
  258.  * same stack frame, using one link instruction at the beginning of the
  259.  * function.
  260.  */
  261. {
  262.     int                                i;
  263.     SpillSlotVia_t                  slot;
  264.     LocAMVia_t                      other;
  265.     SYMVia_t                        list;
  266.     char                            thename[64];
  267.  
  268.     if (!table)
  269.         return;
  270.  
  271.     if (Via(table)->count)
  272.     for (i=1;i<=Via(table)->count;i++) {
  273.         list = TableGetNum(table, i);
  274.         if (list) {
  275.             if (Via(list)->storage_class == SCC_static) {
  276.                 AddStatic(list);
  277.             } else if (Via(list)->storage_class == SCC_extern) {
  278.             #ifdef OLDMEM
  279.                 HLock((Handle) list);
  280.             #endif
  281.                 GetSymName(list,thename);
  282.                 if (GetTPFlags(Via(list)->TP) & ISPASCALMASK) {
  283.                     int                             ndx = 0;
  284.                     while (thename[ndx]) {
  285.                         if (islower(thename[ndx]))
  286.                         thename[ndx] = toupper(thename[ndx]);
  287.                         ndx++;
  288.                     }
  289.                 }
  290.                 if (gProject->itsOptions->bigGlobals) {
  291.                     Via(list)->M68kDef.Loc = BuildLargeGlobal(MakeUserLabel(thename));
  292.                     MakeLocGlobal(Via(list)->M68kDef.Loc);
  293.                 } else {
  294.                     Via(list)->M68kDef.Loc = BuildARegLabelDisplace(5, MakeUserLabel(thename));
  295.                     MakeLocGlobal(Via(list)->M68kDef.Loc);
  296.                 }
  297.                 #ifdef OLDMEM
  298.                 HUnlock((Handle) list);
  299.                 #endif
  300.             SetLocSZ(Via(list)->M68kDef.Loc, M68_TypeSize(GetSymTP(list)));
  301.             if (isFloatingType(GetSymTP(list)))
  302.                 SetLocIsFloat(Via(list)->M68kDef.Loc, 1);
  303.             /* TODO Should generate an XREF here. */
  304.             } else if ((Via(list)->storage_class == SCC_register)) {
  305.                 if (isIntegralType(GetSymTP(list))) {
  306.                     other = PermDataReg();
  307.                     if (other) {
  308.                         SetLocSZ(other, M68_TypeSize(GetSymTP(list)));
  309.                         Via(list)->M68kDef.Loc = other;
  310.                     } else {
  311.                         slot = GetLocalSlot(GetSymTP(list));
  312.                         Via(list)->M68kDef.Loc = Via(slot)->SlotLoc;
  313.                     }
  314.                 } else if (isPointerType(GetSymTP(list))) {
  315.                     other = PermAddrReg();
  316.                     SetLocSZ(other, M68sz_long);
  317.                     if (other) {
  318.                         Via(list)->M68kDef.Loc = other;
  319.                     } else {
  320.                         slot = GetLocalSlot(GetSymTP(list));
  321.                         Via(list)->M68kDef.Loc = Via(slot)->SlotLoc;
  322.                     }
  323.                 } else {
  324.                     slot = GetLocalSlot(GetSymTP(list));
  325.                     Via(list)->M68kDef.Loc = Via(slot)->SlotLoc;
  326.                     if (isFloatingType(GetSymTP(list)))
  327.                         SetLocIsFloat(Via(list)->M68kDef.Loc, 1);
  328.                 }
  329.             } else {
  330.                 slot = GetLocalSlot(GetSymTP(list));
  331.                 Via(list)->M68kDef.Loc = Via(slot)->SlotLoc;
  332.                 if (isFloatingType(GetSymTP(list)))
  333.                     SetLocIsFloat(Via(list)->M68kDef.Loc, 1);
  334.             }
  335.             if (Via(list)->Definition.Initializer) {
  336.                 LocAMVia_t                      res;
  337.                 LocAMVia_t                      postinc;
  338.                 int                             ndx;
  339.                 if (isArithmeticType(GetSymTP(list)) || isPointerType(GetSymTP(list))) {
  340.                     res = GenExpression(Via(list)->Definition.Initializer, Codes);
  341.                     Genmove(GetLocSZ(Via(list)->M68kDef.Loc), res, Via(list)->M68kDef.Loc,
  342.                         Codes);
  343.                     FreeTemp(res);
  344.                 } else {
  345.                     InitDataAccIndex = 0;
  346.                     ImageInit(GetSymTP(list), Via(list)->Definition.Initializer, Codes);
  347.                     /*
  348.                      * Now, move all the bytes in InitDataAcc[] to
  349.                      * Via(list)->M68kDef.Loc
  350.                      */
  351.                     res = TempAddrReg(Codes);
  352.                     GenLoadEA(Via(list)->M68kDef.Loc, res, Codes);
  353.                     postinc = BuildARegPostInc(GetLocAReg(res));
  354.                     ndx = 0;
  355.                     while (ndx < GetTPSize(GetSymTP(list))) {
  356.                     if ((GetTPSize(GetSymTP(list)) - ndx) >= 4) {
  357.                         GenInst(M68op_MOVE, M68sz_long,
  358.                             BuildImmediate((*((long *) &(InitDataAcc[ndx]))), M68sz_long),
  359.                             postinc, Codes);
  360.                         ndx += 4;
  361.                     } else {
  362.                         GenInst(M68op_MOVE, M68sz_word,
  363.                             BuildImmediate((*((short *) &(InitDataAcc[ndx]))), M68sz_word),
  364.                             postinc, Codes);
  365.                         ndx += 2;
  366.                     }
  367.                     }
  368.                     FreeTemp(res);
  369.                 }
  370.             }
  371.         }
  372.     }
  373. }
  374.  
  375. void
  376. GenSymbol(SYMVia_t thesymbol, InstListVia_t Codes)
  377. /*
  378.  * General routine for generating the code for a global symbol. This symbol
  379.  * could be external, static, function, variable, etc...
  380.  */
  381. {
  382.     register SYMVia_t               symbol;
  383.     int                             argoff;
  384.     int                             argbytes = 0;
  385.     if (NumErrors) return;
  386.     symbol = thesymbol;
  387.     if (symbol) {
  388.     if (isFunctionType(GetSymTP(symbol))) {
  389.         if (Via(symbol)->Definition.FuncBody &&
  390.         ((Via(symbol)->storage_class != SCC_extern))) {
  391.         InstVia_t                       last;
  392.         LabSYMVia_t                     labsym;
  393.         LabSYMVia_t                     routsym;
  394.         int                             offset;
  395.         if (GetSymFlags(symbol) & CODEOUTPUT) {
  396.             return;
  397.         }
  398.         /* Don't generate xdef if the routine is static. */
  399.         if (Via(symbol)->storage_class != SCC_static) {
  400.             GenInst(M68op_XDEF, M68sz_none,
  401.                 BuildLabelLoc(GetLocLabel(Via(symbol)->M68kDef.Loc)), NULL, Codes);
  402.         }
  403.         SetSymFlags(symbol, GetSymFlags(symbol) | CODEOUTPUT);
  404.         FreeAllRegs();
  405.         FreePerms();
  406.         KillSpillList();
  407.         SpillList = NULL;
  408.         GenInst(M68op_CSEG, M68sz_none, NULL, NULL, Codes);
  409.         offset = 0;
  410.         labsym = FunctionLastLabel = MakeEccLabel(NextEccLabel++);
  411.         routsym = GetLocLabel(Via(symbol)->M68kDef.Loc);
  412.         GenInst(M68op_EVEN, M68sz_none, NULL, NULL, Codes);
  413.         GenCodeLabel(routsym, Codes);
  414.  
  415.         /*
  416.          * The link instruction is initally generated with a link
  417.          * offset of 0, and the instruction record pointer is held in
  418.          * a global.  As blocks are encountered in the function, the
  419.          * local symbol table for each block is allocated, and this
  420.          * offset is changed directly through the pointer LinkInst.
  421.          */
  422.  
  423.         argoff = 8;    /* This is the offset for the first arg. */
  424.         last = LinkInst = GenInst(M68op_LINK, M68sz_none,
  425.                       BuildARegDirect(FRAME),
  426.                       BuildImmediate(0,
  427.                              M68sz_none), Codes);
  428.         if (isStructUnionType(GetTPBase(GetSymTP(symbol)))) {
  429.             argoff += 4;
  430.             StructDoubleReturnLoc =
  431.             BuildAutoLoc(8, M68_TypeSize(GetTPBase(GetSymTP(symbol))));
  432.             /*
  433.              * If this is a struct valued function, the last argument
  434.              * pushed on the stack is the pointer to the place to
  435.              * store the result.
  436.              */
  437.         }
  438.         if (GetTPFlags(GetSymTP(symbol)) & ISPASCALMASK) {
  439.             if (GetTPMembers(GetSymTP(symbol))) {
  440.                 /* Here we assign location records to each argument. */
  441.                 argbytes = AllocatePascalParameters((GetTPMembers(GetSymTP(symbol))), argoff)
  442.                 - 8;    /* in this way, any hidden struct pointer arg
  443.                      * is remove for pascal functions too. */
  444.             }
  445.             CurrentFunctionPascal = symbol;
  446.             CurrentPascalArgs = argbytes;
  447.         }
  448.         else {
  449.             CurrentFunctionPascal = NULL;
  450.             if (GetTPMembers(GetSymTP(symbol))) {
  451.                 /* Here we assign location records to each argument. */
  452.                 argbytes = AllocateParameters((GetTPMembers(GetSymTP(symbol))), argoff)
  453.                 - 8;    /* in this way, any hidden struct pointer arg
  454.                      * is remove for pascal functions too. */
  455.             }
  456.         }
  457.         /* The actual code generation */
  458.         GenExpression(Via(symbol)->Definition.FuncBody, Codes);
  459.  
  460.         /*
  461.          * Here, after the linkinst and before the rest of the
  462.          * function, if we use any non-temp registers, we need to
  463.          * push them onto the stack.
  464.          */
  465.  
  466.         PushPerms();
  467.  
  468.         GenLabel(labsym, Codes);
  469.  
  470.         /*
  471.          * And, here, if we used any nontemp regs, we need to pop
  472.          * them.
  473.          */
  474.  
  475.         PopPerms(Codes);
  476.  
  477.         last = GenInst(M68op_UNLK, M68sz_none,
  478.                    BuildARegDirect(FRAME),
  479.                    NULL, Codes);
  480.         LinkInst = NULL;
  481.  
  482.         if (GetTPFlags(GetSymTP(symbol)) & ISPASCALMASK) {
  483.             /*
  484.              * Remove it's own arguments from the stack, and push its
  485.              * result, leaving the return address on top. The
  486.              * function pushed the arguments, and then the return
  487.              * address.  We must pop the return address, add to a7 to
  488.              * erase the args, push the result, and push the return
  489.              * address.
  490.              */
  491.             LocAMVia_t                      sp;
  492.             LocAMVia_t                indA7;
  493.             LocAMVia_t                      a0;
  494.             LocAMVia_t                      stkpop;
  495.             LocAMVia_t                      stkpush;
  496.             sp = BuildARegDirect(7);
  497.             a0 = BuildARegDirect(0);
  498.             indA7 = BuildARegIndirect(7);
  499.             stkpop = BuildARegPostInc(7);
  500.             stkpush = BuildARegPreDec(7);
  501.             GenInst(M68op_MOVE, M68sz_long, stkpop, a0, Codes);
  502.             if (argbytes) {
  503.                 GenInst(M68op_ADD, M68sz_long,
  504.                     BuildImmediate(argbytes, M68sz_long), sp, Codes);
  505.             }
  506. #ifdef Undefined
  507.             GenInst(M68op_MOVE, M68_TypeSize(GetTPBase(GetSymTP(symbol))),
  508.                 BuildDRegLocation(0), indA7, Codes);
  509. #endif
  510.             GenInst(M68op_JMP, M68sz_none, BuildARegIndirect(0), NULL, Codes);
  511. #ifdef Undefined
  512.             /* Changed 26 March - better pascal returns */
  513.             GenInst(M68op_MOVE, M68sz_long, a0, stkpush, Codes);
  514.             GenInst(M68op_RTS, M68sz_none, NULL, NULL, Codes);
  515. #endif
  516.         }
  517.         else {
  518.             GenInst(M68op_RTS, M68sz_none, NULL, NULL, Codes);
  519.         }
  520.         if (gProject->itsOptions->MacsBugSymbols)
  521.             GenInst(M68op_MBG, M68sz_none, NULL, NULL, Codes);
  522.         FreeTree(Via(symbol)->Definition.FuncBody);
  523.         Via(symbol)->Definition.FuncBody = NULL;
  524.         } else {        /* No funcbody or extern */
  525.         if (!(GetSymFlags(symbol) & CODEOUTPUT)) {
  526.             SetSymFlags(symbol, GetSymFlags(symbol) | CODEOUTPUT);
  527.             if (!Via(symbol)->Definition.FuncBody)
  528.             GenInst(M68op_XREF, M68sz_none,
  529.                 BuildLabelLoc(GetLocLabel(Via(symbol)->M68kDef.Loc)), NULL, Codes);
  530.         }
  531.         }
  532.     } else {        /* Not a function */
  533.         if (Via(symbol)->storage_class == SCC_extern) {
  534.         if (GetSymFlags(symbol) & REFOUTPUT) {
  535.             return;
  536.         }
  537.         SumGlobalSpace += GetTPSize(GetSymTP(symbol));
  538.         SetSymFlags(symbol, GetSymFlags(symbol) | REFOUTPUT);
  539.         GenInst(M68op_XREF, M68sz_none,
  540.             BuildLabelLoc(GetLocLabel(Via(symbol)->M68kDef.Loc)), NULL, Codes);
  541.         } else {
  542.         if (GetSymFlags(symbol) & CODEOUTPUT) {
  543.             return;
  544.         }
  545.         SumGlobalSpace += GetTPSize(GetSymTP(symbol));
  546.         SetSymFlags(symbol, GetSymFlags(symbol) | CODEOUTPUT);
  547.         SumGlobals += GetTPSize(GetSymTP(symbol));
  548.         if (Via(symbol)->Definition.Initializer) {
  549.             GenInst(M68op_DSEG, M68sz_none, NULL, NULL, Codes);
  550.             GenDataLabel(GetLocLabel(Via(symbol)->M68kDef.Loc), Codes);
  551.             GenInitGlobal(symbol, Codes);
  552.         } else {
  553.             if (GetTPSize(GetSymTP(symbol)) == 1) {
  554.             if (Via(symbol)->storage_class != SCC_static)
  555.                 GenInst(M68op_COMM, M68sz_none,
  556.                     BuildLabelLoc(GetLocLabel(Via(symbol)->M68kDef.Loc)),
  557.                     BuildAbsolute(1), Codes);
  558.             else
  559.                 GenInst(M68op_LCOMM, M68sz_none,
  560.                     BuildLabelLoc(GetLocLabel(Via(symbol)->M68kDef.Loc)),
  561.                     BuildAbsolute(1), Codes);
  562.             OddGlobal = !OddGlobal;
  563.             } else {
  564.             if (OddGlobal) {
  565.                 GenInst(M68op_EVEN, M68sz_none, NULL, NULL, Codes);
  566.                 OddGlobal = 0;
  567.             }
  568.             if (Via(symbol)->storage_class != SCC_static)
  569.                 GenInst(M68op_COMM, M68sz_none,
  570.                     BuildLabelLoc(GetLocLabel(Via(symbol)->M68kDef.Loc)),
  571.                     BuildAbsolute(GetTPSize(GetSymTP(symbol))), Codes);
  572.             else
  573.                 GenInst(M68op_LCOMM, M68sz_none,
  574.                     BuildLabelLoc(GetLocLabel(Via(symbol)->M68kDef.Loc)),
  575.                     BuildAbsolute(GetTPSize(GetSymTP(symbol))), Codes);
  576.             }
  577.         }
  578.         if (Via(symbol)->storage_class != SCC_static) {
  579.             GenInst(M68op_XDEF, M68sz_none,
  580.                 BuildLabelLoc(GetLocLabel(Via(symbol)->M68kDef.Loc)), NULL, Codes);
  581.         }
  582.         }
  583.     }
  584.     }
  585. }
  586.